#ifndef _FLUID_SPARSE_VECTOR_H
#define _FLUID_SPARSE_VECTOR_H


#include <vector>
#include "mathlib.h"

#define NUM_BUCKETS 211
class SimpleHashTable
{
public:
	void SetIndex(const Index3& idx, int realIdx);
	int GetIndex(const Index3& idx);
	SimpleHashTable();
	SimpleHashTable(const SimpleHashTable& rhs);
	~SimpleHashTable();
	const SimpleHashTable& operator= (const SimpleHashTable& rhs);
	void Reset();
private:
	void init();
	void clear();
	void copy(const SimpleHashTable& rhs);
	int hash(const Index3& idx);
	std::vector<Index3>* mIdx3D[NUM_BUCKETS];
	std::vector<int>* mIdx1D[NUM_BUCKETS];
	Index3 mLastHitIdx3D;
	int mLastHitIdx1D;
};


class FluidSparseVector
{
	friend class FLuidSparseMatrix;
	friend class CSRMatrix;
public:
	FluidSparseVector(int numX, int numY, int numZ, int dim);
	FluidSparseVector();
	FluidSparseVector(const FluidSparseVector& rhs);
	const FluidSparseVector& operator= (const FluidSparseVector& rhs);
	~FluidSparseVector();
	void SetZero();
	void SetDimension(int numX, int numY, int numZ, int dim);
	int GetDim() const;
	const FluidSparseVector& operator+= (const FluidSparseVector& rhs);
	const FluidSparseVector& operator-= (const FluidSparseVector& rhs);
	const FluidSparseVector& operator*= (double alpha);
	const FluidSparseVector& operator/= (double alpha);

	void SetValue(int i, int j, int k, double value);
	void AddValue(int i, int j, int k, double value);
	double GetValue(int i, int j, int k) ;

	friend FluidSparseVector operator+(const FluidSparseVector& a, const FluidSparseVector& b);
	friend FluidSparseVector operator-(const FluidSparseVector& a, const FluidSparseVector& b);
	friend FluidSparseVector operator - (const FluidSparseVector &rhs);
	friend FluidSparseVector operator* (double alpha, const FluidSparseVector& rhs);
	friend FluidSparseVector operator/ (double alpha, const FluidSparseVector& rhs);
	std::vector<double> mValues;
	std::vector<Index3> mIndices;
	static double msAccumTime1;
	static double msAccumTime2;
	static double msAccumTime3;
private:
	int mNumX;
	int mNumY;
	int mNumZ;
	int mDim;
	SimpleHashTable* mIndexTable;
	//int*** mIndexTable;

};


#endif